# All content Copyright 2010 Cyrus Omar <cyrus.omar@gmail.com> unless otherwise
# specified.
#
# Contributors:
#     Cyrus Omar <cyrus.omar@gmail.com>
#
# This file is part of, and licensed under the terms of, the atomic-hedgehog
# package.
#
# The atomic-hedgehog package is free software: you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the License,
# or (at your option) any later version.
#
# The atomic-hedgehog package is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with the atomic-hedgehog package. If not, see <http://www.gnu.org/licenses/>.
"""Neuron models live here."""

from ahh.sim import SpikingModel, param, state, local

## Integrate-and-Fire
class GenericIF(SpikingModel):
    """Generic integrate-and-fire with absolute refractory period."""
    def __init__(self, sim, count, basename="GenericIF"):
        SpikingModel.__init__(self, sim, count, basename)

    ## Membrane potential
    @param
    def v_update_eqn(default="v + DT/tau*(I)"):
        """Membrane potential update equation."""

    @param
    def tau():
        """Membrane time constant."""

    @param
    def v_reset():
        """Post-spike reset potential."""

    @param
    def v_thresh():
        """Spike threshold potential."""

    @local
    def v_new():
        """The new value of v will be stored here."""

    @state
    def v(calculations="const cl_type v_new = (abs_refractory_condition) ? v_new : v_update_eqn;",
          spike_updater="v_reset",
          no_spike_updater="v_new"):
        """Membrane potential state variable."""

    @param
    def spike_condition(default="v_new >= v_thresh"):
        """Inherited from SpikingModel."""

    ## Refractory period
    @param
    def abs_refractory_period():
        """Absolute refractory period length."""

    @param
    def abs_refractory_condition(default="t < abs_refractory_t_release"):
        """Boolean condition for absolute refractoriness."""

    @state
    def abs_refractory_t_release(spike_updater="t + abs_refractory_period"):
        """Stores when the absolute refractory period will be released."""

class ReducedLIF(GenericIF):
    """Reduced leaky integrate-and-fire with absolute refractory period."""
    def __init__(self, sim, count, basename="LIF"):
        GenericIF.__init__(self, sim, count, basename)
        pass

    @param
    def I(default="-v"):
        """Reduced leak."""
